<template>
  <div @mousemove="handleMove" @click="handleClick" class="container">
    <canvas ref="canvasRef" width="634" height="591"></canvas>
    <div style="margin: 0 auto; /* 左右居中 */ top: 25px" :style="apuStyle" class="apu"></div>
    <div :style="secStyle" class="sec_ext_pwr"></div>
    <div :style="apuColor" style="left: 340px; top: -58px" class="disc_font">APU</div>
    <div :style="apuColor" style="left: 340px; top: -68px" class="disc_font">GEN</div>
    <div :style="secExtPwrColor" style="left: 210px; top: 30px" class="disc_font">SEC</div>
    <div :style="secExtPwrColor" style="left: 190px; top: 20px" class="disc_font">EXT&nbsp;PWR</div>
    <div :style="extStyle" class="prt_ext_pwr"></div>
    <div :style="prtExtPwrColor" style="left: 375px; top: -60px" class="disc_font">PRT</div>
    <div :style="prtExtPwrColor" style="left: 355px; top: -70px" class="disc_font">
      EXT&nbsp;PWR
    </div>
    <div :style="lMainBus" style="left: 44px; top: -74px" class="bus">L&nbsp;MAIN</div>
    <div :style="rMainBus" style="left: 478px; top: -99px" class="bus">R&nbsp;MAIN</div>
    <div style="top: -98px; left: 105px" :style="lutilBusStyle" class="plainFont">L&nbsp;UTIL</div>
    <div style="top: -105px; left: 90px" :style="lutilBusStyle" class="plainFont">
      LOAD&nbsp;SHED
    </div>
    <div style="top: -148px; left: 480px" :style="rutilBusStyle" class="plainFont">R&nbsp;UTIL</div>
    <div style="top: -156px; left: 450px" :style="rutilBusStyle" class="plainFont">
      LOAD&nbsp;SHED
    </div>
    <div style="top: -116px; left: 50px" :style="genControlStyle1" class="apu"></div>
    <div style="top: -156px; left: 539px" :style="genControlStyle2" class="apu"></div>
    <div :style="lXfrStyle" style="left: 184px; top: -229px" class="bus">L&nbsp;XFR</div>
    <div :style="rXfrStyle" style="left: 335px; top: -254px" class="bus">R&nbsp;XFR</div>
    <div :style="lGenColor" style="left: 95px; top: -250px" class="disc_font">L&nbsp;GEN</div>
    <div :style="lGenColor" style="left: 100px; top: -260px" class="disc_font">CTRL</div>
    <div :style="rGenColor" style="left: 490px; top: -300px" class="disc_font">R&nbsp;GEN</div>
    <div :style="rGenColor" style="left: 495px; top: -310px" class="disc_font">CTRL</div>
    <div style="top: -294px; left: 195px" :style="lBackupStyle" class="apu"></div>
    <div style="top: -334px; left: 392px" :style="rBackupStyle" class="apu"></div>
    <div :style="lBusTieColor" style="left: 130px; top: -650px" class="disc_font">
      L&nbsp;BUS&nbsp;TIE
    </div>
    <div :style="rBusTieColor" style="left: 440px; top: -676px" class="disc_font">
      R&nbsp;BUS&nbsp;TIE
    </div>
    <div :style="lBackupColor" style="left: 212px; top: -390px" class="disc_font">L</div>
    <div :style="rBackupColor" style="left: 408px; top: -410px" class="disc_font">R</div>
    <div style="left: 285px; top: -450px" class="disc_font">BACKUP</div>
    <div style="left: 300px; top: -460px" class="disc_font">GEN</div>
    <div style="left: 46px; top: -536px" :style="lDriveStyle" class="drive"></div>
    <div style="left: 534px; top: -576px" :style="rDriveStyle" class="drive"></div>
    <div style="left: 44px; top: -576px" class="disc_font">L&nbsp;DRIVE</div>
    <div style="left: 530px; top: -602px" class="disc_font">R&nbsp;DRIVE</div>
    <Lower style="top: -590px" />
  </div>
</template>
<script setup>
import { ref, onMounted, reactive, onBeforeUnmount, computed, watch } from 'vue'
import { mapGetters, useStore } from 'vuex'
import Lower from './lower.vue'

const store = useStore()
const canvasRef = ref(null)
const PI = Math.PI

const apuStyle = reactive({
  border: '3px solid rgb(8, 255, 66)'
})

const genControlStyle1 = reactive({
  border: '3px solid rgb(8, 255, 66)'
})

const genControlStyle2 = reactive({
  border: '3px solid rgb(8, 255, 66)'
})

const secStyle = reactive({
  border: '3px solid rgb(255, 255, 255)'
})

const extStyle = reactive({
  border: '3px solid rgb(255, 255, 255)'
})

const lMainBus = reactive({
  border: '3px solid rgb(8, 255, 66)',
  color: 'rgb(8, 255, 66)'
})

const rMainBus = reactive({
  border: '3px solid rgb(8, 255, 66)',
  color: 'rgb(8, 255, 66)'
})

const lXfrStyle = reactive({
  border: '3px solid rgb(8, 255, 66)',
  color: 'rgb(8, 255, 66)'
})

const rXfrStyle = reactive({
  border: '3px solid rgb(8, 255, 66)',
  color: 'rgb(8, 255, 66)'
})

const lBackupStyle = reactive({
  border: '3px solid rgb(8, 255, 66)'
})

const rBackupStyle = reactive({
  border: '3px solid rgb(8, 255, 66)'
})

const lDriveStyle = reactive({
  border: '3px solid rgb(8, 255, 66)'
})

const rDriveStyle = reactive({
  border: '3px solid rgb(8, 255, 66)'
})

const lutilBusStyle = reactive({
  color: 'white'
})

const rutilBusStyle = reactive({
  color: 'white'
})

const apuColor = reactive({
  color: 'rgb(8,214,255)'
})

const lBusTieColor = reactive({
  color: 'rgb(8,214,255)'
})

const rBusTieColor = reactive({
  color: 'rgb(8,214,255)'
})

const secExtPwrColor = reactive({
  color: 'rgb(8,214,255)'
})

const prtExtPwrColor = reactive({
  color: 'rgb(8,214,255)'
})

const lGenColor = reactive({
  color: 'rgb(8,214,255)'
})

const rGenColor = reactive({
  color: 'rgb(8,214,255)'
})

const lBackupColor = reactive({
  color: 'rgb(8,214,255)'
})

const rBackupColor = reactive({
  color: 'rgb(8,214,255)'
})

// 使用 computed 映射 getters
const lBusTie = computed(() => store.getters['elec/lBusTie'])
const rBusTie = computed(() => store.getters['elec/rBusTie'])
const utilBus = computed(() => store.getters['elec/utilBus'])
const lGenCtrl = computed(() => store.getters['elec/lGenCtrl'])
const rGenCtrl = computed(() => store.getters['elec/rGenCtrl'])
const ApuGen = computed(() => store.getters['elec/ApuGen'])
const lBackupGen = computed(() => store.getters['elec/lBackupGen'])
const rBackupGen = computed(() => store.getters['elec/rBackupGen'])
const secExtPwr = computed(() => store.getters['elec/secExtPwr'])
const prtExtPwr = computed(() => store.getters['elec/prtExtPwr'])

watch(
  [
    () => store.getters['elec/lBusTie'],
    () => store.getters['elec/rBusTie'],
    () => store.getters['elec/utilBus'],
    () => store.getters['elec/lGenCtrl'],
    () => store.getters['elec/rGenCtrl'],
    () => store.getters['elec/ApuGen'],
    () => store.getters['elec/lBackupGen'],
    () => store.getters['elec/rBackupGen'],
    () => store.getters['elec/secExtPwr'],
    () => store.getters['elec/prtExtPwr']
  ],
  (newVal, oldVal) => {
    // 遍历新旧值
    newVal.forEach((val, index) => {
      const getterNames = [
        'lBusTie',
        'rBusTie',
        'utilBus',
        'lGenCtrl',
        'rGenCtrl',
        'ApuGen',
        'lBackupGen',
        'rBackupGen',
        'secExtPwr',
        'prtExtPwr'
      ]

      const getterName = getterNames[index]
      const oldValForGetter = oldVal[index]
      const newValForGetter = newVal[index]
      if (newValForGetter !== oldValForGetter) {
        // 根据不同的属性调用不同的方法
        switch (getterName) {
          case 'lBusTie':
            drawCanvas()
            break
          case 'rBusTie':
            drawCanvas()
            break
          case 'utilBus':
            drawCanvas()
            break
          case 'lGenCtrl':
            if (oldValForGetter && !newValForGetter) {
              // true to false - yellow for 2s then white, with yellow X
              genControlStyle1.border = '3px solid yellow'
              genControlStyle1.background = `linear-gradient(45deg, transparent 47%, yellow 47%, yellow 53%, transparent 53%),
                                           linear-gradient(-45deg, transparent 47%, yellow 47%, yellow 53%, transparent 53%)`
              setTimeout(() => {
                genControlStyle1.border = '3px solid rgb(255, 255, 255)'
                genControlStyle1.background = 'none'
              }, 2000)
            } else if (!oldValForGetter && newValForGetter) {
              // false to true - directly to green
              genControlStyle1.border = '3px solid rgb(8, 255, 66)'
            }
            drawCanvas()
            break
          case 'rGenCtrl':
            if (oldValForGetter && !newValForGetter) {
              // true to false - yellow for 2s then white, with yellow X
              genControlStyle2.border = '3px solid yellow'
              genControlStyle2.background = `linear-gradient(45deg, transparent 47%, yellow 47%, yellow 53%, transparent 53%),
                                           linear-gradient(-45deg, transparent 47%, yellow 47%, yellow 53%, transparent 53%)`
              setTimeout(() => {
                genControlStyle2.border = '3px solid rgb(255, 255, 255)'
                genControlStyle2.background = 'none'
              }, 2000)
            } else if (!oldValForGetter && newValForGetter) {
              // false to true - directly to green
              genControlStyle2.border = '3px solid rgb(8, 255, 66)'
            }
            drawCanvas()
            break
          case 'ApuGen':
            apuStyle.border = newValForGetter
              ? '3px solid rgb(8, 255, 66)'
              : '3px solid rgb(255, 255, 255)'
            drawCanvas()
            break
          case 'lBackupGen':
            lBackupStyle.border = newValForGetter
              ? '3px solid rgb(8, 255, 66)'
              : '3px solid rgb(255, 255, 255)'
            drawCanvas()
            break
          case 'rBackupGen':
            rBackupStyle.border = newValForGetter
              ? '3px solid rgb(8, 255, 66)'
              : '3px solid rgb(255, 255, 255)'
            drawCanvas()
            break
          case 'secExtPwr':
            secStyle.border = newValForGetter
              ? '3px solid rgb(8, 255, 66)'
              : '3px solid rgb(255, 255, 255)'
            drawCanvas()
            break
          case 'prtExtPwr':
            extStyle.border = newValForGetter
              ? '3px solid rgb(8, 255, 66)'
              : '3px solid rgb(255, 255, 255)'
            drawCanvas()
            break
          default:
            console.log('Unknown property change')
        }
      }
    })
  }
)

const boxes = [
  { x: 295, y: 85, width: 84, height: 40 },
  { x: 127, y: 125, width: 70, height: 44 },
  { x: 450, y: 125, width: 70, height: 44 },
  { x: 187, y: 186, width: 68, height: 70 },
  { x: 353, y: 186, width: 68, height: 70 },
  { x: 80, y: 296, width: 94, height: 28 },
  { x: 445, y: 296, width: 94, height: 28 },
  { x: 48, y: 369, width: 87, height: 40 },
  { x: 487, y: 369, width: 87, height: 40 },
  { x: 191, y: 423, width: 40, height: 60 },
  { x: 391, y: 423, width: 40, height: 60 }
]

const handleMove = (event) => {
  const x = event.clientX
  const y = event.clientY
  if (
    x >= boxes[0].x &&
    x <= boxes[0].x + boxes[0].width &&
    y >= boxes[0].y &&
    y <= boxes[0].y + boxes[0].height
  ) {
    //设置Apu
    document.body.style.cursor = 'pointer'
    // 当鼠标点击时触发相应的方法
    clickItem = 'apuColor'
    apuColor.color = 'rgb(8,255,66)'
  } else if (
    x >= boxes[1].x &&
    x <= boxes[1].x + boxes[1].width &&
    y >= boxes[1].y &&
    y <= boxes[1].y + boxes[1].height
  ) {
    //设置l bus tie
    document.body.style.cursor = 'pointer'
    // 当鼠标点击时触发相应的方法
    clickItem = 'lBusTie'
    lBusTieColor.color = 'rgb(8,255,66)'
  } else if (
    x >= boxes[2].x &&
    x <= boxes[2].x + boxes[2].width &&
    y >= boxes[2].y &&
    y <= boxes[2].y + boxes[2].height
  ) {
    //设置r bus tie
    document.body.style.cursor = 'pointer'
    // 当鼠标点击时触发相应的方法
    clickItem = 'rBusTie'
    rBusTieColor.color = 'rgb(8,255,66)'
  } else if (
    x >= boxes[3].x &&
    x <= boxes[3].x + boxes[3].width &&
    y >= boxes[3].y &&
    y <= boxes[3].y + boxes[3].height
  ) {
    //设置sec ext pwr
    document.body.style.cursor = 'pointer'
    // 当鼠标点击时触发相应的方法
    clickItem = 'secExtPwr'
    secExtPwrColor.color = 'rgb(8,255,66)'
  } else if (
    x >= boxes[4].x &&
    x <= boxes[4].x + boxes[4].width &&
    y >= boxes[4].y &&
    y <= boxes[4].y + boxes[4].height
  ) {
    //设置prt ext pwr
    document.body.style.cursor = 'pointer'
    // 当鼠标点击时触发相应的方法
    clickItem = 'prtExtPwr'
    prtExtPwrColor.color = 'rgb(8,255,66)'
  } else if (
    (x >= boxes[5].x &&
      x <= boxes[5].x + boxes[5].width &&
      y >= boxes[5].y &&
      y <= boxes[5].y + boxes[5].height) ||
    (x >= boxes[6].x &&
      x <= boxes[6].x + boxes[6].width &&
      y >= boxes[6].y &&
      y <= boxes[6].y + boxes[6].height)
  ) {
    //设置util load shed
    document.body.style.cursor = 'pointer'
    // 当鼠标点击时触发相应的方法
    clickItem = 'utilBus'
    rutilBusStyle.color = 'rgb(8,255,66)'
    lutilBusStyle.color = 'rgb(8,255,66)'
  } else if (
    x >= boxes[7].x &&
    x <= boxes[7].x + boxes[7].width &&
    y >= boxes[7].y &&
    y <= boxes[7].y + boxes[7].height
  ) {
    //设置l gen ctrl
    document.body.style.cursor = 'pointer'
    // 当鼠标点击时触发相应的方法
    clickItem = 'lGenCtrl'
    lGenColor.color = 'rgb(8,255,66)'
  } else if (
    x >= boxes[8].x &&
    x <= boxes[8].x + boxes[8].width &&
    y >= boxes[8].y &&
    y <= boxes[8].y + boxes[8].height
  ) {
    //设置r gen ctrl
    document.body.style.cursor = 'pointer'
    // 当鼠标点击时触发相应的方法
    clickItem = 'rGenCtrl'
    rGenColor.color = 'rgb(8,255,66)'
  } else if (
    x >= boxes[9].x &&
    x <= boxes[9].x + boxes[9].width &&
    y >= boxes[9].y &&
    y <= boxes[9].y + boxes[9].height
  ) {
    //设置l backup gen
    document.body.style.cursor = 'pointer'
    // 当鼠标点击时触发相应的方法
    clickItem = 'lBackupGen'
    lBackupColor.color = 'rgb(8,255,66)'
  } else if (
    x >= boxes[10].x &&
    x <= boxes[10].x + boxes[10].width &&
    y >= boxes[10].y &&
    y <= boxes[10].y + boxes[10].height
  ) {
    //设置r backup gen
    document.body.style.cursor = 'pointer'
    // 当鼠标点击时触发相应的方法
    clickItem = 'rBackupGen'
    rBackupColor.color = 'rgb(8,255,66)'
  } else {
    document.body.style.cursor = 'default'
    if (clickItem) {
      switch (clickItem) {
        case 'apuColor':
          apuColor.color = 'rgb(8,214,255)'
          break
        case 'lBusTie':
          lBusTieColor.color = 'rgb(8,214,255)'
          break
        case 'rBusTie':
          rBusTieColor.color = 'rgb(8,214,255)'
          break
        case 'utilBus':
          lutilBusStyle.color = 'rgb(8,214,255)'
          rutilBusStyle.color = 'rgb(8,214,255)'
          break
        case 'lGenCtrl':
          lGenColor.color = 'rgb(8,214,255)'
          break
        case 'rGenCtrl':
          rGenColor.color = 'rgb(8,214,255)'
          break
        case 'ApuGen':
          apuStyle.color = 'rgb(8,214,255)'
          break
        case 'lBackupGen':
          lBackupColor.color = 'rgb(8,214,255)'
          break
        case 'rBackupGen':
          rBackupColor.color = 'rgb(8,214,255)'
          break
        case 'secExtPwr':
          secExtPwrColor.color = 'rgb(8,214,255)'
          break
        case 'prtExtPwr':
          prtExtPwrColor.color = 'rgb(8,214,255)'
          break
        default:
          console.log('Unknown clickItem')
      }
    }
    clickItem = null
  }
}

let clickItem = null

const handleClick = (event) => {
  if (clickItem) {
    switch (clickItem) {
      case 'apuColor':
        //设置elec.js的apu的状态
        store.dispatch('elec/toggleApuGen')
        break
      case 'lBusTie':
        store.dispatch('elec/toggleLBusTie')
        break
      case 'rBusTie':
        store.dispatch('elec/toggleRBusTie')
        break
      case 'utilBus':
        store.dispatch('elec/toggleUtilBus')
        break
      case 'lGenCtrl':
        store.dispatch('elec/toggleLGenCtrl')
        break
      case 'rGenCtrl':
        store.dispatch('elec/toggleRGenCtrl')
        break
      case 'lBackupGen':
        store.dispatch('elec/toggleLBackupGen')
        break
      case 'rBackupGen':
        store.dispatch('elec/toggleRBackupGen')
        break
      case 'secExtPwr':
        store.dispatch('elec/toggleSecExtPwr')
        break
      case 'prtExtPwr':
        store.dispatch('elec/togglePrtExtPwr')
        break
      default:
        console.log('Unknown clickItem')
    }
  }
}

onMounted(() => {
  drawCanvas()
  window.addEventListener('keydown', handleKeydown) // 在组件挂载时添加键盘事件监听
})

onBeforeUnmount(() => {
  window.removeEventListener('keydown', handleKeydown) // 在组件销毁时移除事件监听
})

const handleKeydown = (event) => {
  // 将按键转换为大写字母
  const key = event.key.toLowerCase()
  const canvas = canvasRef.value
  if (canvas.getContext) {
    const ctx = canvas.getContext('2d')
    const keyActions = {
      q: () => store.dispatch('elec/toggleLBusTie'),
      w: () => store.dispatch('elec/toggleRBusTie'),
      e: () => store.dispatch('elec/toggleUtilBus'),
      r: () => store.dispatch('elec/toggleLGenCtrl'),
      t: () => store.dispatch('elec/toggleRGenCtrl'),
      a: () => store.dispatch('elec/toggleApuGen'),
      s: () => store.dispatch('elec/toggleLBackupGen'),
      d: () => store.dispatch('elec/toggleRBackupGen'),
      f: () => store.dispatch('elec/toggleSecExtPwr'),
      g: () => store.dispatch('elec/togglePrtExtPwr')
    }

    // 如果按键有对应的动作，则执行
    if (keyActions[key]) {
      keyActions[key]()
    }
  }
}

const p0 = 100
const p1 = 140
const p2 = 180
const p3 = 454
const p4 = 494
const p5 = 534
const height = 80

const drawCanvas = () => {
  const canvas = canvasRef.value
  if (canvas.getContext) {
    /**
     * 供电优先级
     * 有以下电源：ApuGen、lBackupGen、rBackupGen、secExtPwr、prtExtPwr、lGenCtrl、rGenCtrl
     */
    const ctx = canvas.getContext('2d')
    // Get all getters from elec store and store in constants
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    // 清除画布的所有内容
    //画BUSTIE
    drawApu(ctx)
    drawSecExtPower(ctx)
    drawExtPwr(ctx)
    drawXfr(ctx)
    drawGen(ctx)
    drawBackUpGen(ctx)
  }
}

const drawApu = (ctx) => {
  let active = false
  if (
    (!lGenCtrlState.value && !rGenCtrlState.value) ||
    (lGenCtrlState.value && !lBusTieState.value) ||
    ((rGenCtrlState.value || prtExtPwrState.value) && !rBusTieState.value)
  ) {
    if (!secExtPwrState.value) {
      active = true
    }
  }
  ctx.beginPath()
  ctx.moveTo((p2 + p3) / 2, height - 15)
  ctx.lineTo((p2 + p3) / 2, height)
  ctx.lineWidth = apuGenState.value && active ? 10 : 2
  ctx.strokeStyle = apuGenState.value && active ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
}

const drawBackUpGen = (ctx) => {
  ctx.beginPath()
  ctx.moveTo(p1 + 110, height + 222)
  ctx.lineTo(p1 + 110, height + 250)
  ctx.lineWidth = 2
  ctx.strokeStyle = 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p4 - 116, height + 222)
  ctx.lineTo(p4 - 116, height + 250)
  ctx.lineWidth = 2
  ctx.strokeStyle = 'white '
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p1 + 80, height + 250)
  ctx.lineTo(p4 - 86, height + 250)
  ctx.lineWidth = 2
  ctx.strokeStyle = 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.arc(p1 + 80, height + 254, 4, Math.PI * 1, Math.PI * 1.5, false)
  ctx.lineWidth = 2
  ctx.strokeStyle = 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.arc(p4 - 86, height + 254, 4, Math.PI * 0, Math.PI * 1.5, true)
  ctx.lineWidth = 2
  ctx.strokeStyle = 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p1 + 76, height + 254)
  ctx.lineTo(p1 + 76, height + 284)
  ctx.lineWidth = 2
  ctx.strokeStyle = 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p4 - 82, height + 254)
  ctx.lineTo(p4 - 82, height + 284)
  ctx.lineWidth = 2
  ctx.strokeStyle = 'white'
  ctx.stroke()
  ctx.closePath()
}

const drawGen = (ctx) => {
  const lGen = store.getters['elec/lGenCtrl']
  const rGen = store.getters['elec/rGenCtrl']
  ctx.beginPath()
  ctx.moveTo(p0 - 30, height + 145)
  ctx.lineTo(p0 - 30, height + 270)
  ctx.lineWidth = lGen ? 10 : 2
  ctx.strokeStyle = lGen ? 'rgb(8,255,66)' : 'rgb(255,255,255)'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p5 + 25, height + 145)
  ctx.lineTo(p5 + 25, height + 270)
  if (!prtExtPwrState.value) {
    ctx.lineWidth = rGen ? 10 : 2
    ctx.strokeStyle = rGen ? 'rgb(8,255,66)' : 'rgb(255,255,255)'
  } else {
    ctx.lineWidth = 2
    ctx.strokeStyle = 'rgb(255,255,255)'
  }
  ctx.stroke()
  ctx.closePath()
}

// Move these computed properties outside drawCanvas so they're accessible everywhere
const lBusTieState = computed(() => store.getters['elec/lBusTie'])
const rBusTieState = computed(() => store.getters['elec/rBusTie'])
const utilBusState = computed(() => store.getters['elec/utilBus'])
const lGenCtrlState = computed(() => store.getters['elec/lGenCtrl'])
const rGenCtrlState = computed(() => store.getters['elec/rGenCtrl'])
const apuGenState = computed(() => store.getters['elec/ApuGen'])
const lBackupGenState = computed(() => store.getters['elec/lBackupGen'])
const rBackupGenState = computed(() => store.getters['elec/rBackupGen'])
const secExtPwrState = computed(() => store.getters['elec/secExtPwr'])
const prtExtPwrState = computed(() => store.getters['elec/prtExtPwr'])

const drawXfr = (ctx) => {
  //到L XFR 汇流条
  const isActiveL =
    lGenCtrlState.value ||
    (lBusTieState.value && (apuGenState.value || secExtPwrState.value)) ||
    (lBusTieState.value && rBusTieState.value && (prtExtPwrState.value || rGenCtrlState.value))
  lXfrStyle.border = isActiveL ? '3px solid rgb(8, 255, 66)' : '3px solid rgb(255, 255, 255)'
  lXfrStyle.color = isActiveL ? 'rgb(8, 255, 66)' : 'rgb(255, 255, 255)'
  lMainBus.border = isActiveL ? '3px solid rgb(8, 255, 66)' : '3px solid rgb(255, 255, 255)'
  lMainBus.color = isActiveL ? 'rgb(8, 255, 66)' : 'rgb(255, 255, 255)'
  ctx.beginPath()
  ctx.moveTo(p1 + 3, height + 132)
  ctx.lineTo(isActiveL ? p1 + 91 : p1 + 95, height + 132)
  ctx.lineWidth = isActiveL ? 10 : 2
  ctx.strokeStyle = isActiveL ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.arc(
    isActiveL ? p1 + 91 : p1 + 95,
    isActiveL ? height + 137 : height + 133,
    isActiveL ? 10 : 2,
    PI * 1,
    0,
    false
  )
  ctx.fillStyle = isActiveL ? 'rgb(8,255,66)' : 'white'
  ctx.fill()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p1 + 96, isActiveL ? height + 137 : height + 133)
  ctx.lineTo(p1 + 96, height + 197)
  ctx.lineWidth = isActiveL ? 10 : 2
  ctx.strokeStyle = isActiveL ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()

  //到 R XFR 汇流条
  const isActiveR =
    rGenCtrlState.value ||
    prtExtPwrState.value ||
    (rBusTieState.value && (apuGenState.value || secExtPwrState.value)) ||
    (lBusTieState.value && rBusTieState.value && lGenCtrlState.value)
  rXfrStyle.border = isActiveR ? '3px solid rgb(8, 255, 66)' : '3px solid rgb(255, 255, 255)'
  rXfrStyle.color = isActiveR ? 'rgb(8, 255, 66)' : 'rgb(255, 255, 255)'
  rMainBus.border = isActiveR ? '3px solid rgb(8, 255, 66)' : '3px solid rgb(255, 255, 255)'
  rMainBus.color = isActiveR ? 'rgb(8, 255, 66)' : 'rgb(255, 255, 255)'
  ctx.beginPath()
  ctx.moveTo(p4 - 15, height + 132)
  ctx.lineTo(isActiveR ? p4 - 103 : p4 - 107, height + 132)
  ctx.lineWidth = isActiveR ? 10 : 2
  ctx.strokeStyle = isActiveR ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.arc(
    isActiveR ? p4 - 103 : p4 - 107,
    isActiveR ? height + 137 : height + 133,
    isActiveR ? 10 : 2,
    PI * 1,
    0,
    false
  )
  ctx.fillStyle = isActiveR ? 'rgb(8,255,66)' : 'white'
  ctx.fill()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p4 - 108, isActiveR ? height + 137 : height + 133)
  ctx.lineTo(p4 - 108, height + 197)
  ctx.lineWidth = isActiveR ? 10 : 2
  ctx.strokeStyle = isActiveR ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  drawUtilLoadShed(ctx, isActiveL, isActiveR)
  drawBusTie(ctx, isActiveL, isActiveR)
}

const drawUtilLoadShed = (ctx, isActiveL, isActiveR) => {
  const utilBus = store.getters['elec/utilBus']
  //l util load shed
  ctx.beginPath()
  ctx.moveTo(p0 - 16, height + 144)
  ctx.lineTo(p0 - 16, height + 158)
  ctx.lineWidth = 2
  ctx.strokeStyle = utilBus && isActiveL ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.arc(p0 - 12, height + 158, 4, PI * 1, PI * 0.5, true)
  ctx.lineWidth = 2
  ctx.strokeStyle = utilBus && isActiveL ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p0 - 12, height + 162)
  ctx.lineTo(p0 - 2, height + 162)
  ctx.lineWidth = 2
  ctx.strokeStyle = utilBus && isActiveL ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  // r util load shed
  ctx.beginPath()
  ctx.moveTo(p5 + 12, height + 144)
  ctx.lineTo(p5 + 12, height + 158)
  ctx.lineWidth = 2
  ctx.strokeStyle = utilBus && isActiveR ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.arc(p5 + 8, height + 158, 4, PI * 0.5, 0, true)
  ctx.lineWidth = 2
  ctx.strokeStyle = utilBus && isActiveR ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p5 + 8, height + 162)
  ctx.lineTo(p5 - 2, height + 162)
  ctx.lineWidth = 2
  ctx.strokeStyle = utilBus && isActiveR ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
}

const drawExtPwr = (ctx) => {
  ctx.beginPath()
  ctx.moveTo(p3 - 40, height + 60)
  ctx.lineTo(p3 + 60, height + 60)
  ctx.lineWidth = prtExtPwrState.value ? 10 : 2
  ctx.strokeStyle = prtExtPwrState.value ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.arc(p3 + 60, height + 64, 4, PI * 1.5, 0, false)
  ctx.lineWidth = prtExtPwrState.value ? 10 : 2
  ctx.strokeStyle = prtExtPwrState.value ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p3 + 64, height + 64)
  ctx.lineTo(p3 + 64, height + 120)
  ctx.lineWidth = prtExtPwrState.value ? 10 : 2
  ctx.strokeStyle = prtExtPwrState.value ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
}

const drawBusTie = (ctx, isActiveL, isActiveR) => {
  let activeLbusTie = lBusTieState.value
  let activeRbusTie = rBusTieState.value

  if (lBusTieState.value && rBusTieState.value) {
    //由于无法并联供电，当左右bus tie都打开时，要考虑如下情况
    /**
     * 1.如果左发电机供电，右发电机或者PRT EXT PWR也供电，则两个bustie 断开此时分别供电
     * 2.如果左发电机供电，右发电机和RT EXT PWR都不供电，但是APU或者SEC EXT PWR供电，则L BUS TIE断开，R BUS TIE闭合
     */
    if (lGenCtrlState.value && (rGenCtrlState.value || prtExtPwrState.value)) {
      activeLbusTie = false
      activeRbusTie = false
    } else if (secExtPwrState.value && prtExtPwrState.value) {
      activeLbusTie = true
      activeRbusTie = false
    }
  } else {
    /**
     * 如果左右bus tie有一个打开了，则要考虑如下情况
     * 1.如果l bus tie 闭合，此时如果左发电机供电，APU或者SEC EXT PWR供电，则L BUS TIE断开
     * 2.如果r bus tie 闭合，此时如果右发动机或 prt ext pwr供电，且APU或者SEC EXT PWR供电则R BUS TIE断开
     */
    if (lBusTieState.value) {
      if (lGenCtrlState.value && (apuGenState.value || secExtPwrState.value)) {
        activeLbusTie = false
      }
    }
    if (rBusTieState.value) {
      if (
        (rGenCtrlState.value || prtExtPwrState.value) &&
        (apuGenState.value || secExtPwrState.value)
      ) {
        activeRbusTie = false
      }
    }
  }

  ctx.beginPath()
  ctx.moveTo(p0, height)
  ctx.lineTo(p1, height)
  ctx.lineWidth = isActiveL ? 10 : 2
  ctx.strokeStyle = isActiveL ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  //画连接到L MAIN的线
  ctx.beginPath()
  ctx.arc(p1 - 40, height + 4, 4, PI * 1.5, PI * 1, true)
  ctx.lineWidth = isActiveL ? 10 : 2
  ctx.strokeStyle = isActiveL ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p1 - 44, height + 4)
  ctx.lineTo(p1 - 44, height + 120)
  ctx.lineWidth = isActiveL ? 10 : 2
  ctx.strokeStyle = isActiveL ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()

  //画L BUS TIE 到 L MAIN BUS
  const isActiveBusTie =
    apuGenState.value ||
    secExtPwrState.value ||
    (lBusTieState.value && isActiveL) ||
    (rBusTieState.value && isActiveR)
  ctx.beginPath()
  ctx.moveTo(p2, height)
  ctx.lineTo(p3, height)
  ctx.lineWidth = isActiveBusTie ? 10 : 2
  ctx.strokeStyle = isActiveBusTie ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()

  //画连接到R MIAN的线
  ctx.beginPath()
  ctx.moveTo(p4, height)
  ctx.lineTo(p5, height)
  ctx.lineWidth = isActiveR ? 10 : 2
  ctx.strokeStyle = isActiveR ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.arc(p4 + 40, height + 4, 4, PI * 2, PI * 1.5, true)
  ctx.lineWidth = isActiveR ? 10 : 2
  ctx.strokeStyle = isActiveR ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo(p4 + 44, height + 4)
  ctx.lineTo(p4 + 44, height + 120)
  ctx.lineWidth = isActiveR ? 10 : 2
  ctx.strokeStyle = isActiveR ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  //设置左busTie
  drawLBusTieSwitch(ctx, isActiveBusTie, isActiveL, activeLbusTie)
  drawRBusTieSwitch(ctx, isActiveBusTie, isActiveR, activeRbusTie)
}

/**
 * 画右busTie开关
 * @param ctx
 * @param activeBusTie r bus tie 与 l bus tie 之间是否有电
 * @param activeRbusTie R BUS TIE 右边是否有电
 * @param rBusTie R BUS TIE 开关是否可以闭合
 */
const drawRBusTieSwitch = (ctx, activeBusTie, activeRbusTie, rBusTie) => {
  // 计算开关中心点坐标
  const centerX = (p3 + p4) / 2

  // 根据不同状态设置颜色
  let active = false
  let color = 'rgb(255,198,41)' // 默认黄色(未连接)
  if (!rBusTieState.value) {
    color = 'white' // 白色(已连接无电)
    active = false // 开关断开
  } else {
    if (rBusTie) {
      if (activeBusTie || activeRbusTie) {
        color = 'rgb(8,255,55)' // 绿色(有电)
        active = true
      }
    }
  }

  // 设置基础样式
  ctx.lineWidth = 2
  ctx.strokeStyle = color

  // 绘制开关横线
  ctx.beginPath()
  ctx.moveTo(centerX - 12, active ? height - 8 : height - 12)
  ctx.lineTo(centerX + 12, active ? height - 8 : height - 12)
  ctx.stroke()
  ctx.closePath()

  // 绘制开关竖线上部
  ctx.beginPath()
  ctx.moveTo(centerX, active ? height - 8 : height - 12)
  ctx.lineTo(centerX, active ? height + 1 : height - 3)
  ctx.stroke()
  ctx.closePath()

  // 绘制开关竖线下部
  ctx.beginPath()
  ctx.moveTo(centerX, height + 1)
  ctx.lineTo(centerX, height + 7)
  ctx.stroke()
  ctx.closePath()

  // 绘制左右两侧圆点
  ctx.beginPath()
  ctx.arc(p3 + 5, height, 4, PI * 2, 0, true)
  ctx.stroke()
  ctx.closePath()

  ctx.beginPath()
  ctx.arc(p4 - 5, height, 4, PI * 2, 0, true)
  ctx.stroke()
  ctx.closePath()
}

/**
 * 画左busTie开关
 * @param ctx
 * @param activeBusTie l bus tie 与 r bus tie 之间是否有电
 * @param activeLbusTie L BUS TIE 左边是否有电
 * @param lBusTie L BUS TIE 开关是否可以闭合
 */
const drawLBusTieSwitch = (ctx, activeBusTie, activeLbusTie, lBusTie) => {
  // 计算开关中心点坐标
  const centerX = (p1 + p2) / 2

  // 设置基础样式
  ctx.lineWidth = 2
  let active = false
  // 根据不同状态绘制开关
  let color = 'rgb(255,198,41)' // 默认黄色(未连接)
  if (!lBusTieState.value) {
    color = 'white' // 白色(已连接无电)
    active = false // 开关断开
  } else {
    if (lBusTie) {
      if (activeLbusTie || activeBusTie) {
        color = 'rgb(8,255,55)' // 绿色(有电)
        active = true // 开关闭合
      }
    }
  }

  // 绘制开关横线
  ctx.beginPath()
  ctx.moveTo(centerX - 12, active ? height - 8 : height - 12)
  ctx.lineTo(centerX + 12, active ? height - 8 : height - 12)
  ctx.strokeStyle = color
  ctx.stroke()
  ctx.closePath()

  // 绘制开关竖线上部
  ctx.beginPath()
  ctx.moveTo(centerX, active ? height - 8 : height - 12)
  ctx.lineTo(centerX, active ? height + 1 : height - 3)
  ctx.strokeStyle = color
  ctx.stroke()
  ctx.closePath()

  // 绘制开关竖线下部
  ctx.beginPath()
  ctx.moveTo(centerX, height + 1)
  ctx.lineTo(centerX, height + 7)
  ctx.strokeStyle = color
  ctx.stroke()
  ctx.closePath()

  // 绘制左右两侧圆点
  ctx.beginPath()
  ctx.arc(p1 + 5, height, 4, PI * 2, 0, true)
  ctx.strokeStyle = color
  ctx.stroke()
  ctx.closePath()

  ctx.beginPath()
  ctx.arc(p2 - 5, height, 4, PI * 2, 0, true)
  ctx.strokeStyle = color
  ctx.stroke()
  ctx.closePath()
}

const drawSecExtPower = (ctx) => {
  let active = false
  if (
    (!lGenCtrlState.value && !rGenCtrlState.value) ||
    (lGenCtrlState.value && !lBusTieState.value) ||
    ((rGenCtrlState.value || prtExtPwrState.value) && !rBusTieState.value)
  ) {
    active = true
  }
  //画连接到SEC EXT PWR的线
  ctx.beginPath()
  ctx.moveTo((p2 + p3) / 2, height)
  ctx.lineTo((p2 + p3) / 2, height + 60)
  ctx.lineWidth = secExtPwrState.value && active ? 10 : 2
  ctx.strokeStyle = secExtPwrState.value && active ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.arc((p2 + p3) / 2 - 4, height + 60, 4, PI * 0.5, 0, true)
  ctx.lineWidth = secExtPwrState.value && active ? 10 : 2
  ctx.strokeStyle = secExtPwrState.value && active ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
  ctx.beginPath()
  ctx.moveTo((p2 + p3) / 2 - 4, height + 64)
  ctx.lineTo((p2 + p3) / 2 - 70, height + 64)
  ctx.lineWidth = secExtPwrState.value && active ? 10 : 2
  ctx.strokeStyle = secExtPwrState.value && active ? 'rgb(8,255,66)' : 'white'
  ctx.stroke()
  ctx.closePath()
}
</script>

<style scoped>
/* Canvas的定位和样式 */
canvas {
  position: absolute;
  top: 0;
  left: 0;
}

.container {
  height: 591px;
  width: 634px;
  position: relative;
  z-index: 10;
}

.apu {
  position: relative;
  height: 40px;
  width: 40px;
  border-radius: 2px;
}

.drive {
  position: relative;
  height: 40px;
  width: 50px;
  border-radius: 2px;
}

.sec_ext_pwr {
  position: relative;
  top: 85px;
  left: 198px;
  height: 40px;
  width: 50px;
  border-radius: 2px;
}

.prt_ext_pwr {
  position: relative;
  top: -58px;
  left: 364px;
  height: 40px;
  width: 50px;
  border-radius: 2px;
}

.bus {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 25px;
  width: 100px;
  font-weight: 600;
  height: 25px;
}

.plainFont {
  position: relative;
  font-weight: 600;
}

.disc_font {
  position: relative;
  color: rgb(8, 214, 255);
  font-weight: 600;
}
.white_font {
  position: relative;
  color: rgb(255, 255, 255);
  font-weight: 600;
  font-size: 18px;
}
</style>
